{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# ![xtensor](images/xtensor.png)\n",
        "\n",
        "<center>Multi-dimensional arrays with broadcasting and lazy computing.</center>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Introduction\n",
        "\n",
        "`xtensor` is a C++ library meant for numerical analysis with multi-dimensional array expressions.\n",
        "\n",
        "`xtensor` provides\n",
        "\n",
        " - an extensible expression system enabling **lazy broadcasting**.\n",
        " - an API following the idioms of the **C++ standard library**.\n",
        " - tools to manipulate array expressions and build upon `xtensor`.\n",
        "\n",
        "The implementation of the containers of `xtensor` is inspired by [NumPy](http://www.numpy.org), the Python array programming library. **Adaptors** for existing data structures to be plugged into our expression system can easily be written. In fact, `xtensor` can be used to **process `NumPy` data structures inplace** using Python's [buffer protocol](https://docs.python.org/3/c-api/buffer.html).\n",
        "\n",
        "`xtensor` requires a modern C++ compiler supporting C++14. The following C+ compilers are supported:\n",
        "\n",
        " - On Windows platforms, Visual C++ 2015 Update 2, or more recent\n",
        " - On Unix platforms, gcc 4.9 or a recent version of Clang"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Usage\n",
        "\n",
        "<div style=\"background: #efffed;\n",
        "            border: 1px solid grey;\n",
        "            margin: 8px 0 8px 0;\n",
        "            text-align: center;\n",
        "            padding: 8px; \">\n",
        "    <i class=\"fa-play fa\" \n",
        "       style=\"font-size: 40px;\n",
        "              line-height: 40px;\n",
        "              margin: 8px;\n",
        "              color: #444;\">\n",
        "    </i>\n",
        "    <div>\n",
        "    To run the selected code cell, hit <pre style=\"background: #efffed\">Shift + Enter</pre>\n",
        "    </div>\n",
        "</div>\n",
        "\n",
        "\n",
        "### Initialize a 2-D array and compute the sum of one of its rows and a 1-D array"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "#include <iostream>\n",
        "\n",
        "#include \"xtensor/xarray.hpp\"\n",
        "#include \"xtensor/xio.hpp\"\n",
        "#include \"xtensor/xview.hpp\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xarray<double> arr1\n",
        "  {{1.0, 2.0, 3.0},\n",
        "   {2.0, 5.0, 7.0},\n",
        "   {2.0, 5.0, 7.0}};\n",
        "\n",
        "xt::xarray<double> arr2\n",
        "  {5.0, 6.0, 7.0};\n",
        "\n",
        "xt::view(arr1, 1) + arr2"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "arr1"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Initialize a 1-D array and reshape it inplace"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "#include <iostream>\n",
        "#include \"xtensor/xarray.hpp\"\n",
        "#include \"xtensor/xio.hpp\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xarray<int> arr\n",
        "  {1, 2, 3, 4, 5, 6, 7, 8, 9};\n",
        "\n",
        "arr.reshape({3, 3});\n",
        "\n",
        "arr"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Broadcasting the ``xt::pow`` universal functions"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "#include <iostream>\n",
        "#include \"xtensor/xarray.hpp\"\n",
        "#include \"xtensor/xmath.hpp\"\n",
        "#include \"xtensor/xio.hpp\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xarray<double> arr3\n",
        "  {1.0, 2.0, 3.0};\n",
        "\n",
        "xt::xarray<unsigned int> arr4\n",
        "  {4, 5, 6, 7};\n",
        "\n",
        "arr4.reshape({4, 1});\n",
        "\n",
        "xt::pow(arr3, arr4)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Random arrays with the random module"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "#include <iostream>\n",
        "#include \"xtensor/xrandom.hpp\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xarray<double> arr5 = xt::random::randn<double>({4, 3});\n",
        "arr5"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "scrolled": true
      },
      "outputs": [],
      "source": [
        "xt::random::randn<double>({5, 3, 8, 10}) > 0.2"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Using `linspace`, `arange`, `ones`, `zeros`"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "#include \"xtensor/xbuilder.hpp\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xarray<double> ar = xt::linspace<double>(0.0, 10.0, 12);\n",
        "ar.reshape({4, 3});\n",
        "ar"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xarray<double> fones = xt::ones<float>({2, 2});\n",
        "fones"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::arange<int>(1569325055)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Using `xt::broadcast`"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "#include <vector>\n",
        "#include \"xtensor/xbroadcast.hpp\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::broadcast(xt::linspace<double>(0.0, 10.0, 4),\n",
        "              std::vector<std::size_t>({3, 4}))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Using standard algorithms with xexpressions"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "#include <algorithm>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xarray<double> frand = xt::random::randn<double>({2, 2});\n",
        "\n",
        "// begin() and end() provide and iterator pair iterating over the xexpression in a row-major fashion\n",
        "std::cout << std::accumulate(frand.begin(), frand.end(), 0.0);\n",
        "\n",
        "frand"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Iterating over a prescribed broadcasted shape"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "// begin(shape) and end(shape) provide and iterator pair iterating\n",
        "// over the xexpression broadcasted to the prescrived shape in a row-major fashion\n",
        "std::vector<std::size_t> shape = {3, 2, 2};\n",
        "std::cout << std::accumulate(frand.begin(shape), frand.end(shape), 0.0);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# ![xtensor-blas](images/xtensor-blas.png)\n",
        "\n",
        "<center>Blas bindings for xtensor.</center>\n",
        "\n",
        "`xtensor-blas` is an extension to the xtensor library, offering bindings to BLAS and LAPACK libraries \n",
        "through cxxblas and cxxlapack from the [FLENS](https://github.com/michael-lehn/FLENS) project.\n",
        "\n",
        "`xtensor-blas` currently provides non-broadcasting `dot`, `norm` (1- and 2-norm for vectors), `inverse`, `solve`,\n",
        "`eig`, `cross`, `det`, `slogdet`, `matrix_rank`, `inv`, `cholesky`, `qr`, `svd` in the `xt::linalg` namespace (check the corresponding `xlinalg.hpp` header for the function signatures). The functions, and signatures, are trying to be 1-to-1 equivalent to NumPy.\n",
        "Low-level functions to interface with BLAS or LAPACK with xtensor containers are also offered \n",
        "in the `blas` and `lapack` namespace.\n",
        "\n",
        "`xtensor` and `xtensor-blas` require a modern C++ compiler supporting C++14. The following C++ compilers are supported:\n",
        "\n",
        " - On Windows platforms, Visual C++ 2015 Update 2, or more recent\n",
        " - On Unix platforms, gcc 4.9 or a recent version of Clang"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "#include \"xtensor-blas/xlinalg.hpp\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xtensor<double, 2> m = {{1.5, 0.5}, {0.7, 1.0}};"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "std::cout << \"Matrix rank: \" << std::endl << xt::linalg::matrix_rank(m);"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "std::cout << \"Matrix inverse: \" << std::endl << xt::linalg::inv(m);"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "std::cout << \"Eigen values: \" << std::endl << xt::linalg::eigvals(m);"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "xt::xarray<double> arg1 = xt::arange<double>(9);\n",
        "xt::xarray<double> arg2 = xt::arange<double>(18);\n",
        "arg1.reshape({3, 3});\n",
        "arg2.reshape({2, 3, 3});\n",
        "std::cout << xt::linalg::dot(arg1, arg2) << std::endl;"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "C++14",
      "language": "C++14",
      "name": "xcpp14"
    },
    "language_info": {
      "version": "-std=c++14",
      "codemirror_mode": "text/x-c++src",
      "file_extension": ".cpp",
      "mimetype": "text/x-c++src",
      "name": "c++"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}
